package com.liaogui.framework.protocol;

import com.liaogui.framework.protocol.DisPatcherServlet;
import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;

/**
 * @author liaogui
 * @date 2025/4/16 17:55
 */
public class HttpServer {
    /**
     * 启动Tomcat → 配置端口 → 构建Engine/Host/Context → 注册Servlet → 启动并等待
     *
     * @param hostname 主机名
     * @param port     港口
     */
    public static void start(String hostname, Integer port) {
        // 创建一个内嵌的Tomcat实例，用于后续配置和启动。
        Tomcat tomcat = new Tomcat();
        // Server代表整个Tomcat服务器
        Server server = tomcat.getServer();
        // Service是Server中的服务组件，默认名为"Tomcat"。每个Service包含一个容器（如Engine）和多个连接器（Connector）。
        Service service = server.findService("Tomcat");
        // 创建连接器并设置监听端口（如8080），负责处理HTTP请求。
        Connector connector = new Connector();
        connector.setPort(port);

        // Engine是Tomcat的顶层容器，代表一个完整的Servlet引擎。
        Engine engine =  new StandardEngine();
        engine.setDefaultHost(hostname);
        // StandardHost表示虚拟主机，设置为默认主机
        StandardHost host = new StandardHost();
        host.setName(hostname);
        // StandardContext表示一个Web应用，contextPath设置为空字符串，表示根路径（如http://localhost:8080/
        String contextPath = "";
        StandardContext context = new StandardContext();
        context.setPath(contextPath);
        // Tomcat.FixContextListener是Tomcat内置的监听器，用于修复上下文配置
        context.addLifecycleListener(new Tomcat.FixContextListener());

        host.addChild(context);
        engine.addChild(host);

        // 将Engine设置为Service的容器，使请求能够通过连接器传递到容器处理。
        service.setContainer(engine);
        // 将连接器添加到Service中，使服务能够通过该端口接收请求。
        service.addConnector(connector);

        // 注册名为dispatcher的Servlet（实际类为DispatcherServlet）。
        tomcat.addServlet(contextPath, "dispatcher", new DisPatcherServlet());
        // 将Servlet映射到所有URL路径（/*），处理所有请求。
        context.addServletMappingDecoded("/*", "dispatcher");

        try {
            // 启动Tomcat服务器
            tomcat.start();
            System.out.println("=======启动成功=======");
            // 阻塞主线程，防止程序退出，直到服务器关闭。
            tomcat.getServer().await();
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        }
    }
}

